<template>
  <div class="home">
    <div class="home_header">
      <el-button type="primary" size="small" @click="setMode('RECT')"
      >矩形
      </el-button
      >
      <el-button type="primary" size="small" @click="setMode('POLYGON')"
      >多边形
      </el-button
      >
    </div>
    <div class="pic_content">
      <div class="maps" id="map"></div>
      <div class="tag_content" v-if="tagVisible" :style="{left: tranLeft, top: tranTop}">
        <div class="tag_header">
          <div class="tag_header_left">标注</div>
          <div class="tag_header_right">
            <i class="el-icon-close" @click="handleCloseTag"></i>
          </div>
        </div>
        <div class="tag_list">
          <div class="tag_item" v-for="(item, index) in tagList" :key="index"
               @click="handleTag(item,index)"
          >
            <div
              class="tag_item_color"
              :style="{ backgroundColor: item.color }"
            ></div>
            <div class="tag_item_name">{{ item.name }}</div>
            <div class="tag_item_index">{{ index + 1 }}</div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import AILabel from "ailabel";

import CircularJSON from "circular-json";

export default {
  name: "home",
  data() {
    return {
      gMap: null, // 标注容器
      imgUrl: require("@/assets/images/ai_bj1.png"),
      drawingStyle: {},
      editId: "", //待填充图形id
      mode: "",
      itemName: "",
      gFirstFeatureLayer: null, //矢量图层实例(矩形，多边形等矢量)
      allFeatures: null, //所有features
      gFirstTextLayer: null, // 文本层
      tagList: [
        {
          id: 1,
          name: "安全帽",
          color: "rgba(88,36,25,0.2)"
        },
        {
          id: 2,
          name: "反光衣",
          color: "rgba(188,203,25,0.2)"
        }
      ],
      tranLeft: "",
      tranTop: "",
      currentType: "",
      currentData: null,
      currentId: "",
      tagVisible: false
    };
  },
  watch: {
    mode(mode) {
      this.gMap.setMode(mode);
      this.setDrawingStyle(mode);
    }
  },
  mounted() {
    this.initMap();
  },
  beforeDestroy() {
    this.gMap.destroy();
  },
  methods: {
    initMap() {
      let that = this;
      const gMap = new AILabel.Map("map", {
        center: { x: 400, y: 300 }, // 为了让图片居中
        zoom: 800,
        mode: "RECT", // 绘制线段
        refreshDelayWhenZooming: false, // 缩放时是否允许刷新延时，性能更优
        zoomWhenDrawing: false,
        panWhenDrawing: false
        // zoomWheelRatio: 5, // 控制滑轮缩放缩率[0, 10), 值越小，则缩放越快，反之越慢
        // withHotKeys: true // 关闭快捷键
      });
      that.gMap = gMap;
      this.addEvent();
      // 图片层添加
      const gFirstImageLayer = new AILabel.Layer.Image(
        "first-layer-image", // id
        {
          src: that.imgUrl,
          width: 800,
          height: 600,
          crossOrigin: false, // 如果跨域图片，需要设置为true
          position: {
            // 左上角相对中心点偏移量
            x: 0,
            y: 0
          }
          // 网格
          /*grid: {
            // 3 * 3
            columns: [{ color: "#9370DB" }, { color: "#FF6347" }],
            rows: [{ color: "#9370DB" }, { color: "#FF6347" }]
          }*/
        }, // imageInfo
        { name: "第一个图片图层" }, // props
        { zIndex: 5 } // style
      );
      // 添加到gMap对象
      gMap.addLayer(gFirstImageLayer);
      // 添加矢量图层
      const gFirstFeatureLayer = new AILabel.Layer.Feature(
        "first-layer-feature", // id
        { name: "第一个矢量图层" }, // props
        { zIndex: 10 } // style
      );
      this.gFirstFeatureLayer = gFirstFeatureLayer;
      gMap.addLayer(gFirstFeatureLayer);

      // 添加文本层
      this.gFirstTextLayer = new AILabel.Layer.Text(
        "first-layer-text", // id
        { name: "第一个文本图层" }, // props
        { zIndex: 12, opacity: 1 } // style
      );
      gMap.addLayer(this.gFirstTextLayer);

      this.setMode("RECT");
      this.initData();
      window.onresize = function() {
        this.gMap && this.gMap.resize();
      };
    },
    initData() {
      const allFeatures = sessionStorage.getItem("allFeatures");
      if (!allFeatures) {
        return;
      }
      const array = JSON.parse(allFeatures);
      console.log(666777, array);
      let rectFeature; // 添加矩形
      let gFirstFeaturePolygon; // 添加多边形
      let gFirstText; // 添加文字
      array.forEach((ele) => {
        if (ele.type === "RECT") {
          rectFeature = new AILabel.Feature.Rect(
            ele.id, // id
            ele.shape, // shape
            ele.props, // props
            ele.style // style
          );
          this.gFirstFeatureLayer.addFeature(rectFeature);
          // 判断是否有 text
          if (ele.props && ele.props.text) {
            gFirstText = new AILabel.Text(
              ele.props.textId, // id
              {
                text: ele.props.text,
                position: { x: ele.shape.x, y: ele.shape.y },
                offset: { x: 0, y: 0 }
              }, // shape, 左上角
              {
                name: "第一个文本对象",
                textId: ele.props.textId,
                deleteMarkerId: ele.props.deleteMarkerId
              }, // props
              {
                fillStyle: "#F4A460",
                strokeStyle: "#D2691E",
                background: true,
                globalAlpha: 1,
                fontColor: "#0f0"
              } // style
            );
            this.gFirstTextLayer.addText(gFirstText);
          }
        } else if (ele.type == "POLYGON") {
          console.log(989, ele);
          gFirstFeaturePolygon = new AILabel.Feature.Polygon(
            ele.id, // id
            ele.shape, // shape
            ele.props, // props
            ele.style // style
          );
          this.gFirstFeatureLayer.addFeature(gFirstFeaturePolygon);
          if (ele.props && ele.props.text) {
            gFirstText = new AILabel.Text(
              ele.props.textId, // id, // id
              {
                text: ele.props.text,
                position: ele.shape.points[0],
                offset: { x: 0, y: 0 }
              }, // shape, 左上角
              {
                name: "第一个文本对象",
                textId: ele.props.textId,
                deleteMarkerId: ele.props.deleteMarkerId
              }, // props
              {
                fillStyle: "#F4A460",
                strokeStyle: "#D2691E",
                background: true,
                globalAlpha: 1,
                fontColor: "#0f0"
              } // style
            );
            this.gFirstTextLayer.addText(gFirstText);
          }
        }
      });
    },
    setMode(mode) {
      console.log(555);
      this.mode = mode;
    },
    handleCloseTag() {
      this.tagVisible = false;
    },
    handleTag(item, index) {
      console.log(111, item);
      this.itemName = item.name;
      this.addFeature(this.currentData, this.currentType, this.currentId);
      this.handleCloseTag();
    },
    // 增加事件
    addEvent() {
      let that = this;
      let gMap = this.gMap;
      gMap.events.on("drawDone", (type, data) => {
        console.log("--type, data--", type, data);
        this.tagVisible = true;
        this.itemName = "";
        this.currentType = type;
        this.currentData = data;
        // this.itemName = "测试";
        this.currentId = `label-text-id-${+new Date()}`;
        that.addFeature(data, type, this.currentId);
        if (type === "RECT") {
          this.tranLeft = data.x + data.width + 20 + "px";
          this.tranTop = data.y + "px";
        } else if (type === "POLYGON") {
          const array = data.sort((a, b) => {
            return b.x - a.x;
          });
          const array1 = data.sort((a, b) => {
            return a.y - b.y;
          });
          console.log(2323, array, array1);
          this.tranLeft = data[0].x + 20 + "px";
          this.tranTop = data[0].y + "px";
        }


        /* if (type == "CLEARMASK" || type == "DRAWMASK") {
           that.addFeature(data, type);
         } else {
           that.getName(type).then((id) => {
             if (id) {
               that.addFeature(data, type, id);
             } else {
               this.$message({
                 type: "info",
                 message: "请填写名字"
               });
             }
           });
         }*/
      });
      gMap.events.on("boundsChanged", (data) => {
        console.log("--map boundsChanged--", data);
        return "";
      });
      // 双击编辑 在绘制模式下双击feature触发选中
      gMap.events.on("featureSelected", (feature) => {
        this.editId = feature.id;
        console.log("--map featureSelected--", feature, "双击编辑");
        //设置编辑feature
        gMap.setActiveFeature(feature);
        if (feature.type != "POINT") {
          // 增加删除按钮
          that.addDeleteIcon(feature, feature.shape);
        }
      });
      //右键 目前只针对点双击选中右键触发
      gMap.events.on("featureDeleted", (feature) => {
        if (feature.type == "POINT") {
          // 根据id删除对应feature
          that.gFirstFeatureLayer.removeFeatureById(feature.id);
        }
      });
      // 单机空白取消编辑
      gMap.events.on("featureUnselected", () => {
        // 取消featureSelected
        that.editId = "";
        that.deIcon();
        gMap.setActiveFeature(null);
      });
      // 更新完
      gMap.events.on("featureUpdated", (feature, shape) => {
        console.log(feature);
        // 更新或者移动需要重新设置删除图标
        that.deIcon();
        feature.updateShape(shape);
        if (feature.type != "POINT") {
          that.addDeleteIcon(feature, shape);
        }
      });

      // 删除
      gMap.events.on("FeatureDeleted", () => {
        console.log(2222222);
        // that.gFirstFeatureLayer.removeFeatureById(that.editId);
      });
    },
    // 初始样式
    setDrawingStyle(mode) {
      let drawingStyle = {};
      switch (mode) {
        //平移
        case "PAN": {
          break;
        }
        //注记
        case "MARKER": {
          // 忽略
          break;
        }
        //点
        case "POINT": {
          this.drawingStyle = { fillStyle: "#FF8C00" };
          this.gMap.setDrawingStyle(drawingStyle);
          break;
        }
        //圆
        case "CIRCLE": {
          this.drawingStyle = {
            fillStyle: "#87CEFF",
            strokeStyle: "#87CEFF",
            lineWidth: 5
          };
          this.gMap.setDrawingStyle(drawingStyle);
          break;
        }
        //线段
        case "LINE": {
          this.drawingStyle = {
            strokeStyle: "#BA55D3",
            lineJoin: "round",
            lineCap: "round",
            lineWidth: 10,
            arrow: false
          };
          this.gMap.setDrawingStyle(drawingStyle);
          break;
        }
        //多线段
        case "POLYLINE": {
          this.drawingStyle = {
            strokeStyle: "#FF1493",
            lineJoin: "round",
            lineCap: "round",
            lineWidth: 10
          };
          this.gMap.setDrawingStyle(drawingStyle);
          break;
        }
        //矩形
        case "RECT": {
          this.drawingStyle = { strokeStyle: "#0f0", lineWidth: 1 };
          this.gMap.setDrawingStyle(drawingStyle);
          break;
        }
        //多边形
        case "POLYGON": {
          this.drawingStyle = {
            strokeStyle: "#0099CC", //边框颜色
            fill: true, //是否填充
            fillStyle: "#FF6666", //填充色
            globalAlpha: 0.3,
            lineWidth: 3,
            fill: true,
            stroke: true
          };
          this.gMap.setDrawingStyle(drawingStyle);
          break;
        }
        //涂抹
        case "DRAWMASK": {
          this.drawingStyle = {
            strokeStyle: "rgba(255, 0, 0, .5)",
            fillStyle: "#00f",
            lineWidth: 50
          };
          this.gMap.setDrawingStyle(drawingStyle);
          break;
        }
        //擦除
        case "CLEARMASK": {
          this.drawingStyle = { fillStyle: "#00f", lineWidth: 30 };
          this.gMap.setDrawingStyle(drawingStyle);
          break;
        }
        default:
          break;
      }
    },
    // 添加图形
    addFeature(data, type, id) {
      let that = this;
      let drawingStyle = this.drawingStyle;
      const relatedTextId = this.currentId; //`label-text-id-${+new Date()}`;
      const relatedDeleteMarkerId = `label-marker-id-${+new Date()}`;
      //线
      if (type === "LINE") {
        const scale = that.gMap.getScale();
        const width = drawingStyle.lineWidth / scale;
        const lineFeature = new AILabel.Feature.Line(
          id, // id
          { ...data, width }, // shape
          { name }, // props
          drawingStyle // style
        );
        that.gFirstFeatureLayer.addFeature(lineFeature);
      }
      //线段
      else if (type === "POLYLINE") {
        const scale = that.gMap.getScale();
        const width = drawingStyle.lineWidth / scale;
        const polylineFeature = new AILabel.Feature.Polyline(
          id, // id
          { points: data, width }, // shape
          { name }, // props
          drawingStyle // style
        );
        that.gFirstFeatureLayer.addFeature(polylineFeature);
      }
      //矩形
      else if (type === "RECT") {
        console.log("9998,", data, type, id, name);
        const rectFeature = new AILabel.Feature.Rect(
          id, // id
          data, // shape
          // { name }, // props
          {
            name: "矢量图形",
            textId: relatedTextId,
            deleteMarkerId: relatedDeleteMarkerId,
            text: this.itemName
          }, // props
          drawingStyle // style
        );
        that.gFirstFeatureLayer.addFeature(rectFeature);
        // 添加feature标签名
        const { x: ltx, y: lty } = data;
        const gFirstText = new AILabel.Text(
          relatedTextId, // id
          {
            text: this.itemName,
            position: { x: ltx, y: lty },
            offset: { x: 0, y: 0 }
          }, // shape, 左上角
          {
            name: "第一个文本对象",
            textId: relatedTextId,
            deleteMarkerId: relatedDeleteMarkerId
          }, // props
          {
            fillStyle: "#F4A460",
            strokeStyle: "#D2691E",
            background: true,
            globalAlpha: 1,
            fontColor: "#0f0"
          } // style
        );
        this.gFirstTextLayer.addText(gFirstText);
      }
      //多边形
      else if (type === "POLYGON") {
        const polygonFeature = new AILabel.Feature.Polygon(
          relatedDeleteMarkerId, // id
          { points: data }, // shape
          {
            name: "矢量图形2",
            textId: relatedTextId,
            deleteMarkerId: relatedDeleteMarkerId,
            text: this.itemName
          }, // props
          drawingStyle // style
        );
        that.gFirstFeatureLayer.addFeature(polygonFeature);
        // 添加feature标签名
        const { x: ltx, y: lty } = data[0];
        const gFirstText = new AILabel.Text(
          relatedTextId, // id
          {
            text: this.itemName,
            position: { x: ltx, y: lty },
            offset: { x: 0, y: 0 }
          }, // shape, 左上角
          {
            name: "第一个文本对象",
            textId: relatedTextId,
            deleteMarkerId: relatedDeleteMarkerId
          }, // props
          {
            fillStyle: "#F4A460",
            strokeStyle: "#D2691E",
            background: true,
            globalAlpha: 1,
            fontColor: "#0f0"
          } // style
        );
        this.gFirstTextLayer.addText(gFirstText);
      }
      //点
      else if (type == "POINT") {
        const gFirstFeaturePoint = new AILabel.Feature.Point(
          id, // id
          { x: data.x, y: data.y, r: 5 }, // shape
          { name }, // props
          { fillStyle: "#FF8C00", zIndex: 5, lineWidth: 2 } // style
        );
        that.gFirstFeatureLayer.addFeature(gFirstFeaturePoint);
      }
      //注记
      else if (type == "MARKER") {
        const gFirstMarker = new AILabel.Marker(
          id, // id
          {
            src: "http://ailabel.com.cn/public/ailabel/demo/marker.png",
            position: {
              // marker坐标位置
              x: data.x,
              y: data.y
            },
            offset: {
              x: -16,
              y: 32
            }
          }, // markerInfo
          { name: "第一个marker注记" } // props
        );
        that.gFirstFeatureLayer.addFeature(gFirstMarker);
      }
      //圆
      else if (type == "CIRCLE") {
        const gFirstFeatureCircle = new AILabel.Feature.Circle(
          id, // id
          { cx: data.cx, cy: data.cy, r: data.r }, // shape
          { name: "第一个矢量图层" }, // props
          {
            fillStyle: "#87CEFF",
            strokeStyle: "#3CB371",
            globalAlpha: 1,
            lineWidth: 5
          } // style
        );
        that.gFirstFeatureLayer.addFeature(gFirstFeatureCircle);
      }
      //涂抹
      else if (type == "DRAWMASK") {
        const drawMaskAction = new AILabel.Mask.Draw(
          `${+new Date()}`, // id
          "铅笔",
          { points: data, width: 5 }, // shape
          { name: "港币", price: "1元" }, // props
          { strokeStyle: "#FF0000" } // style
        );
        that.gFirstFeatureLayer.addAction(drawMaskAction);
      }
      //擦除
      else if (type == "CLEARMASK") {
        const clearMaskAction = new AILabel.Mask.Clear(
          "first-action-clear", // id
          { points: data, width: 5 } // shape
        );
        that.gFirstMaskLayer.addAction(clearMaskAction);
      }
      this.getFeatures();
    },
    // 画完取名
    getName(mode) {
      return this.$prompt("请输入填写名字", {
        confirmButtonText: "确定",
        showCancelButton: false
      })
        .then(({ value }) => {
          this.itemName = value;
          return value;
        })
        .catch(() => {
          return null;
        });
    },
    // 增加删除图标
    addDeleteIcon(feature, shape) {
      let gMap = this.gMap;
      let that = this;
      let features = null;
      // 添加delete-icon
      // let points = that.getPoints(feature);
      console.log(shape, feature, "shape");
      if (feature.type == "POLYGON") {
        // console.log(feature.shape.points);
        const array = shape.points;
        let array1 = array.sort((a, b) => {
          return b.x - a.x;
        });
        console.log(666, array1);
        features = array1[0];
      } else if (feature.type == "RECT") {
        features = feature.getPoints()[1];
      }
      const gFirstMarker = new AILabel.Marker(
        that.deleteIconId, // id
        {
          src: require("@/assets/images/delete.png"),
          // position: { x: shape.x + shape.width, y: shape.y - 15 }, // 矩形右上角 根据图形动态调整
          position: features,
          offset: {
            x: -20,
            y: -4
          }
        }, // markerInfo
        { name: "delete" } // props
      );
      gFirstMarker.events.on("click", (marker) => {
        // 首先删除当前marker
        gMap.markerLayer.removeMarkerById(marker.id);
        // 删除对应text
        this.gFirstTextLayer.removeTextById(feature.props.textId);
        // 删除对应feature
        that.gFirstFeatureLayer.removeFeatureById(feature.id);
      });
      gMap.markerLayer.addMarker(gFirstMarker);

      // that.gFirstFeatureLayer
    },
    // 删除 删除按钮
    deIcon() {
      this.gMap.markerLayer.removeAllMarkers();
    },
    // 获取所有features
    getFeatures() {
      this.allFeatures = this.gFirstFeatureLayer.getAllFeatures();
      console.log("--allFeatures--", this.allFeatures);
      /*const array = [];
      this.allFeatures.map((item) => {
        array.push(CircularJSON.parse(CircularJSON.stringify(item)));
      });
      sessionStorage.setItem("allFeatures", CircularJSON.stringify(array));*/
    },
    circularSafeStringify(obj) {
      const cache = new Set();
      return JSON.stringify(obj, (key, value) => {
        if (typeof value === "object" && value !== null) {
          /*if (cache.has(value)) {
            // 当前对象已经存在于缓存中，说明存在循环引用，返回占位符或其他处理方式
            return "[Circular Reference]";
          }*/
          cache.add(value);
        }
        return value;
      });
    }
  }
};
</script>

<style scoped lang="less">
.home {
  .home_header {
    display: flex;
    align-items: center;
    justify-content: center;
    margin-top: 20px;
  }

  .pic_content {
    width: 800px;
    height: 600px;
    margin: 0 auto;
    margin-top: 20px;
    border: 1px solid #76ff5f;
    position: relative;

    .maps {
      width: 800px;
      height: 600px;
    }

    /*img {
      width: 100%;
      height: 100%;
    }*/

    .tag_content {
      width: 200px;
      display: block;
      position: absolute;
      z-index: 100;
      background: white;
      border: 1px solid #eeeeee;

      .tag_header {
        display: flex;
        align-items: center;
        justify-content: space-between;
        height: 32px;
        padding: 0 10px;

        .tag_header_left {
          color: #252525;
          font-size: 13px;
        }

        .tag_header_right {
          color: #252525;
          font-size: 18px;
          cursor: pointer;
        }
      }

      .tag_list {
        width: 100%;

        .tag_item {
          display: flex;
          align-items: center;
          height: 32px;
          padding: 0 10px;
          cursor: pointer;

          &:hover {
            background: #eeeeee;
          }

          .tag_item_color {
            width: 8px;
            height: 16px;
          }

          .tag_item_name {
            font-size: 12px;
            color: #252525;
            flex: 1;
            margin-left: 10px;
            margin-right: 10px;
          }

          .tag_item_index {
            font-size: 12px;
            color: #252525;
          }
        }
      }
    }
  }
}
</style>
